package com.huiminpay.transaction.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.huiminpay.common.cache.Cache;
import com.huiminpay.common.cache.domain.BusinessException;
import com.huiminpay.common.cache.domain.CommonErrorCode;
import com.huiminpay.common.cache.util.RedisUtil;
import com.huiminpay.transaction.api.dto.PayChannelDTO;
import com.huiminpay.transaction.api.dto.PayChannelParamDTO;
import com.huiminpay.transaction.api.dto.PlatformChannelDTO;
import com.huiminpay.transaction.api.service.PayChannelService;
import com.huiminpay.transaction.convert.PayChannelParamConvert;
import com.huiminpay.transaction.convert.PlatformChannelConvert;
import com.huiminpay.transaction.entity.AppPlatformChannel;
import com.huiminpay.transaction.entity.PayChannelParam;
import com.huiminpay.transaction.entity.PlatformChannel;
import com.huiminpay.transaction.mapper.AppPlatformChannelMapper;
import com.huiminpay.transaction.mapper.PayChannelParamMapper;
import com.huiminpay.transaction.mapper.PlatformChannelMapper;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.Service;
import org.omg.CORBA.PUBLIC_MEMBER;
import org.springframework.beans.factory.annotation.Autowired;

import javax.annotation.Resource;
import javax.swing.plaf.PanelUI;
import java.util.List;
@Service
public class PayChannelServiceImpl implements PayChannelService {
   @Autowired
   private PlatformChannelMapper platformChannelMapper;
   @Autowired
   private AppPlatformChannelMapper appPlatformChannelMapper;
   @Autowired
   private PayChannelParamMapper payChannelParamMapper;
   @Resource
   private Cache cache;

    @Override
    public List<PlatformChannelDTO> queryPlatformChannel() throws BusinessException {
        List<PlatformChannel> platformChannels = platformChannelMapper.selectList(null);
        List<PlatformChannelDTO> platformChannelDTOS = PlatformChannelConvert.INSTANCE.listentity2listdto(platformChannels);
        return platformChannelDTOS;
    }
    @Override
    public void isBindPlatform(String appId, String platformChannelCodes) throws BusinessException {
        LambdaQueryWrapper<AppPlatformChannel> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(AppPlatformChannel::getAppId,appId).eq(AppPlatformChannel::getPlatformChannel,platformChannelCodes);
        AppPlatformChannel appPlatformChannel = appPlatformChannelMapper.selectOne(wrapper);
        if (appPlatformChannel==null){
            appPlatformChannel= new AppPlatformChannel();
            appPlatformChannel.setAppId(appId);
            appPlatformChannel.setPlatformChannel(platformChannelCodes);
            appPlatformChannelMapper.insert(appPlatformChannel);
        }
    }
    @Override
    public int queryIsBind(String appId, String platformChannel) throws BusinessException {
        LambdaQueryWrapper<AppPlatformChannel> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(AppPlatformChannel::getAppId,appId).eq(AppPlatformChannel::getPlatformChannel,platformChannel);
        Integer num = appPlatformChannelMapper.selectCount(wrapper);
        if (num>0){
            return 1;
        }
        return 0;
    }

    @Override
    public List<PayChannelDTO> queryPayChannelByPatformChannel(String platfomChannelCode) throws BusinessException {
        List<PayChannelDTO> payChannelDTOS = platformChannelMapper.queryPayChannelByPatformChannel(platfomChannelCode);
        return payChannelDTOS;
    }
    @Override
    public void savePayChannelParam(PayChannelParamDTO payChannelParamDTO) throws BusinessException {
           //参数校验
        if (payChannelParamDTO==null||payChannelParamDTO.getMerchantId()==null ||payChannelParamDTO.getAppId()==null
                ||payChannelParamDTO.getPlatformChannelCode()==null ||payChannelParamDTO.getPayChannel()==null){
            throw new BusinessException(CommonErrorCode.E_300009);
        }
        //查询应用绑定商户平台id
        Long appPlatformChannelId = this.queryAppPlatformChannelId(payChannelParamDTO.getAppId(),
                payChannelParamDTO.getPlatformChannelCode());
        if (appPlatformChannelId==null){
            throw new BusinessException(CommonErrorCode.E_300010);
        }
        LambdaQueryWrapper<PayChannelParam> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PayChannelParam::getAppPlatformChannelId,appPlatformChannelId).
                eq(PayChannelParam::getPayChannel,payChannelParamDTO.getPayChannel());
        PayChannelParam payChannelParam = payChannelParamMapper.selectOne(wrapper);
        if (payChannelParam==null){
            PayChannelParam entity = PayChannelParamConvert.INSTANCE.dto2entity(payChannelParamDTO);
            entity.setAppPlatformChannelId(appPlatformChannelId);
            payChannelParamMapper.insert(entity);
        }else {
            payChannelParam.setChannelName(payChannelParamDTO.getChannelName());
            payChannelParam.setParam(payChannelParamDTO.getParam());
            payChannelParamMapper.updateById(payChannelParam);
        }
        //更新缓存
        this.update(payChannelParamDTO.getAppId(),payChannelParamDTO.getPlatformChannelCode());


    }
    //redis更新
    private void update(String appId, String platformChannel){
        String key = RedisUtil.keyBuilder(appId, platformChannel);
        String value = cache.get(key);
        if (!StringUtils.isEmpty(value)){
            cache.del(key);
        }
        List<PayChannelParamDTO> payChannelParamDTOS = this.
                queryListPayChannelParamByappIdandPlatformChannel(appId, platformChannel);
        String jsonStr = JSONObject.toJSONString(payChannelParamDTOS);
        cache.set(key,jsonStr);
    }
    @Override
    public List<PayChannelParamDTO> queryListPayChannelParamByappIdandPlatformChannel(String appId, String platformChannel) throws BusinessException {
        String key = RedisUtil.keyBuilder(appId, platformChannel);
        String value = cache.get(key);
        if (!StringUtils.isEmpty(value)){
            return JSONObject.parseArray(value, PayChannelParamDTO.class);
        }
        AppPlatformChannel appPlatformChannel = appPlatformChannelMapper.selectOne(new LambdaQueryWrapper<AppPlatformChannel>().eq(AppPlatformChannel::getAppId, appId).
                eq(AppPlatformChannel::getPlatformChannel, platformChannel));
        if (appPlatformChannel==null){
           return null;
        }
        Long appPlatformChannelId = appPlatformChannel.getId();
        List<PayChannelParam> payChannelParams = payChannelParamMapper.selectList(new LambdaQueryWrapper<PayChannelParam>()
                .eq(PayChannelParam::getAppPlatformChannelId, appPlatformChannelId));
        List<PayChannelParamDTO> payChannelParamDTOS = PayChannelParamConvert.INSTANCE.listentity2listdto(payChannelParams);
        cache.set(key,JSONObject.toJSONString(payChannelParamDTOS));
        return payChannelParamDTOS;
    }
    @Override
    public PayChannelParamDTO queryPayChannelParamByappIdandPlatformChannel(String appId,
                                                                            String platformChannel, String payChannel)
            throws BusinessException {
        Long appPlatformChannelId = this.queryAppPlatformChannelId(appId, platformChannel);
//        List<PayChannelParamDTO> payChannelParamDTOS = this.
//                queryListPayChannelParamByappIdandPlatformChannel(appId, platformChannel);
//        for (PayChannelParamDTO payChannelParamDTO:payChannelParamDTOS){
//            if (payChannelParamDTO.getPayChannel().equals(payChannel)){
//                return payChannelParamDTO;
//            }
//        }
//        return null;
        PayChannelParam payChannelParam = payChannelParamMapper.selectOne(new LambdaQueryWrapper<PayChannelParam>().
                eq(PayChannelParam::getAppPlatformChannelId, appPlatformChannelId).
                eq(PayChannelParam::getPayChannel, payChannel));
        PayChannelParamDTO payChannelParamDTO = PayChannelParamConvert.INSTANCE.entity2dto(payChannelParam);
        return payChannelParamDTO;
    }

   //获取AppPlatformChannelId
    private Long queryAppPlatformChannelId(String appId,String platformChannelCode){
        LambdaQueryWrapper<AppPlatformChannel> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(AppPlatformChannel::getAppId,appId).
                eq(AppPlatformChannel::getPlatformChannel,platformChannelCode);
        AppPlatformChannel appPlatformChannel = appPlatformChannelMapper.selectOne(wrapper);
        if (appPlatformChannel!=null){
            return appPlatformChannel.getId();
        }
        return null;
    }

}
